/***************************************************************************
 *   mgpi_errors.h - Errors Handling Interface Definitions                 *
 *   Copyright (C) 2008 by cmaster.matso                                   *
 *   cmaster.matso@gmail.com                                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

#include "mgpi_errors.h"

static char *s_pShortMessageString = MGPI_NOERROR;                              /** short message string */
static char s_aMessageHeader[] = "\n --- MGPI Messages Listing --- \n\n";       /** messaging system header string */
static void *s_pMsgRef = NULL;                                                  /** short message data pointer */
static msgnode_t *s_pMessagesList = NULL;                                       /** messages list pointer */
static int s_nMessageCount = 0;                                                 /** messages counter */

/**
 * Adds a message node to the messages list.
 */
static void s_AddMessageNode(char *message, void *vparam) {
    msgnode_t *iter = s_pMessagesList, *temp;

    if (!s_pMessagesList) {
        s_pMessagesList = (msgnode_t *) calloc(1, sizeof (msgnode_t));
        s_pMessagesList->prev = NULL;
        s_pMessagesList->next = NULL;
        s_pMessagesList->message = message;
        s_pMessagesList->vparam = vparam;
        s_nMessageCount++;
        return;
    }

    while (iter->next) iter = iter->next;
    temp = (msgnode_t *) calloc(1, sizeof (msgnode_t));
    iter->next = temp;
    temp->prev = iter;
    temp->message = message;
    temp->vparam = vparam;
    s_nMessageCount++;
    return;
}

/**
 * Gets the short message string.
 */
const char *MGPI_GetMessage(void) {
    return (const char*) s_pShortMessageString;
}

/**
 * Causes the message string to be set to a proper message containing given string.
 */
void MGPI_PostMessage(const char *string, void *vparam) {
    s_pMsgRef = vparam;
    sprintf(s_pShortMessageString, "--- MGPI Message ---\n \t%p, %s\n", vparam, string);
    return;
}

/**
 * Adds a message to the messages list with the given formated message string.
 */
void MGPI_PostMessagef(const char *message, ...) {
    va_list ap;
    char *error = (char *) calloc(2048, sizeof (char));

    va_start(ap, message);
    vsprintf(error, message, ap);
    va_end(ap);

    s_AddMessageNode(error, NULL);
    return;
}

/**
 * Gets the last called message string.
 */
const char *MGPI_GetLastMessage(void) {
    msgnode_t *iter = s_pMessagesList;
    while (iter->next) iter = iter->next;
    return (const char *) iter->message;
}

/**
 * Gets the last called message node.
 */
msgnode_t *MGPI_GetLastMessageNode(void) {
    msgnode_t *iter = s_pMessagesList;
    while (iter->next) iter = iter->next;
    return iter;
}

/**
 * Prints all messages from the list to the given stream.
 */
int MGPI_GetMessages(FILE *stream) {
    msgnode_t *iter = s_pMessagesList;
    int i = 0;

    if (!stream) {
        MGPI_PostMessagef("%s: given stream pointer is a null pointer: stream = %p", __FUN__, stream);
        return 0;
    }

    if (!s_pMessagesList) {
        fprintf(stream, "%s\n", MGPI_NOERROR);
        return (!0);
    }

    fprintf(stream, s_aMessageHeader);
    while (i < s_nMessageCount) {
        fprintf(stream, ">>> %s\n\n", iter->message);

        if (!iter->next) {
			free(iter->message);
            free(iter);
            return (!0);
        }

        iter = iter->next;
        iter->prev->next = NULL;
        if (iter->prev && iter->prev->message) free(iter->prev->message);
        if (iter->prev) free(iter->prev);
        iter->prev = NULL;
        ++i;
    }
    return (!0);
}
